from flask import g
from flask import request
from flask_restful.inputs import int_range
from flask_restful.reqparse import RequestParser
from flask_restful import Resource

from cache.comment import ArticleCommentReplyCache, CommentCache, ArticleCommentCache
from cache.saticstic import CommentReplyCountStorage
from cache.user import UserCommentLikingCache
from models.news import Comment,CommentLiking
from toutiao import db
from .constants import DEFAULT_COMMENT_PER_PAGE_MIN, DEFAULT_COMMENT_PER_PAGE_MAX
from toutiao.utils.decorators import loginrequired


class Comments(Resource):
    # 登陆用户操作
    method_decorators = [loginrequired]

    def post(self):
        # 接受校验数据
        parser = RequestParser()
        parser.add_argument('target', location='json', required=True, type=int)
        parser.add_argument('content', location='json', required=True)
        parser.add_argument('art_id', location='json')
        args = parser.parse_args()

        # 获取到的参数
        target = args.target
        content = args.content
        art_id = args.art_id

        # 保存前段传来的数据
        comment = Comment(user_id=g.user_id, article_id=target, content=content)
        if art_id:
            # 回复评论
            comment.parent_id = target
            comment.article_id = art_id

            # 评论的回复数量增加计数
            CommentReplyCountStorage.incr(target)

        db.session.add(comment)
        # 保存
        db.session.commit()
        # 返回响应
        return {"com_id": comment.id, "target": target}, 201

    def get(self):
        # 获取参数和数据
        parser = RequestParser()
        parser.add_argument('type', location='args', required=True)
        parser.add_argument('source', location='args', required=True, type=int)
        # offset 最好设置一下 验证类型
        parser.add_argument('offset', location='args', type=int)
        # 设置了下分页的上下限       int_rang(low, high,参数)
        parser.add_argument('limit', location='args', type=int_range(DEFAULT_COMMENT_PER_PAGE_MIN,
                                                                     DEFAULT_COMMENT_PER_PAGE_MAX,
                                                                     'limit'))
        # 验证参数
        args = parser.parse_args()
        offset = args.offset
        source = args.source
        type = args.get('type')
        # limit空的话给他一个默认值后面的那个10,不是空就是前面的数
        limit = args.limit if args.limit is not None else DEFAULT_COMMENT_PER_PAGE_MIN

        # # 根据评论类型区分
        # # type(query) str 是	评论类型，a表示文章评论 c表示回复评论
        # if args.type == 'a':
        #     # 查询评论文章的     条件是  文章id  被评论的id  审核过的  排序是倒序,越是新评价的自增数字越大
        #     comments = Comment.query.filter_by(article_id=source, parent_id=None,
        #                                        status=Comment.STATUS.APPROVED).order_by(Comment.id.desc()).all()
        # # 回复评论
        # else:
        #     comments = Comment.query.filter_by(parent_id=comment_id, status=Comment.STATUS.APPROVED).order_by(
        #         Comment.id.desc()).all()
        #     pass
        # # 初始化一些变量
        # total_count = len(comments)  # 评论总数
        # page_comments = []  # 指定分页的数据
        # end_id = None  # 所有评论的最后一个的时间戳
        # last_id = None  # 当前分页的最后一条的时间戳
        # item_count = 0  # 计数器
        # page_last_comment = None  # 记录分页最后一个的记录
        #
        # # 遍历
        # for comment in comments:
        #     # 创建时间戳
        #     score = comment.ctime.timestamp()
        #     # 通过offset时间戳来获取评论
        #     # 1 offset不是空的时候 需要score<offset  然后我们取10个数据
        #     # 2 offset是none的时候 我们只取0-10个数据
        #     if ((offset is not None and score < offset) or offset is None) and item_count <= DEFAULT_COMMENT_PER_PAGE_MIN:
        #         # 我们就获取第一页的评论数据  一页10条
        #         # 构造数据,传入
        #         page_comments.append({
        #             'com_id': comment.id,
        #             'aut_id': comment.user.id,
        #             'aut_name': comment.user.name,
        #             'aut_photo': comment.user.profile_photo,
        #             'pubdate': comment.ctime.strftime('%Y-%m-%d %H:%M:%S'),
        #             'content': comment.content,
        #             'is_top': comment.is_top,
        #             'is_liking': False,
        #             'reply_count': 0
        #         })
        #         item_count += 1
        #         page_last_comment = comment
        #
        # if total_count > 0:
        #     # 所有评论的最后一个
        #     end_id = comments[-1].ctime.timestamp()
        #     # 获取本页的最后一条　　遍历中最后的数就是当前最后的数
        #     last_id = page_last_comment.ctime.timestamp() if page_last_comment is not None else None
        if type == 'a':
            total_count, end_id, last_id, page_comments_ids = ArticleCommentCache(source).get_page(offset, limit)

            page_comments = []
            for comment_id in page_comments_ids:
                c = CommentCache(comment_id).get()
                # 判断评论是否被点赞
                is_liking=UserCommentLikingCache(g.user_id).user_liking_comment(comment_id)
                c['is_liking'] = is_liking

                # 统计回复数量
                reply_count = CommentReplyCountStorage.get(comment_id)
                c['reply_count'] = reply_count

                page_comments.append(c)
            ArticleCommentCache(source).clear()
            # 返回相应
            return {
                "total_count": total_count,
                "end_id": end_id,
                "last_id": last_id,  # 本次请求最后一条评论的id, 作为下次请求的offset, 无值返回None
                "results": page_comments
            }

        # 获取有回复的评论
        else:
            # # 1查询有回复的评论
            # comments = Comment.query.filter_by(parent_id=source, status=Comment.STATUS.APPROVED).order_by(
            #     Comment.id.desc()).all()
            # # 2初始化化一些数据变量 (同评论部分)
            # total_count = len(comments)
            # end_id = None
            # last_id = None
            # item_count = 0
            # page_last_comment = None
            # page_comments = []
            # # 遍历所有有回复的评论
            # for comment in comments:
            #     # 添加时间戳
            #     score = comment.ctime.timestamp()
            #
            #     if ((offset is not None and score < offset) or offset is None) and item_count <= 10:
            #         page_comments.append({
            #             'com_id': comment.id,
            #             'aut_id': comment.user.id,
            #             'aut_name': comment.user.name,
            #             'aut_photo': comment.user.profile_photo,
            #             'pubdate': comment.ctime.strftime('%Y-%m-%d %H:%M:%S'),
            #             'content': comment.content,
            #             'is_top': comment.is_top,
            #             'is_liking': False,
            #             'reply_count': 0
            #         })
            #         item_count += 1  # 遍历计数
            #         page_last_comment = comment
            # if total_count>0:
            #     end_id=comments[-1].ctime.timestamp()
            #     last_id=page_last_comment.ctime.timestamp() if page_last_comment is not None else None
            total_count, end_id, last_id, page_comments_ids = ArticleCommentReplyCache(source).get_page(offset, limit)

            page_comments = []
            for comment_id in page_comments_ids:
                c = CommentCache(comment_id).get()
                page_comments.append(c)
            ArticleCommentReplyCache(source).clear()
            # 5.返回相应
            return {'total_count': total_count, 'end_id': end_id, 'last_id': last_id, 'results': page_comments}


# 评论点赞
class CommentLikingResource(Resource):
    method_decorators = [loginrequired]

    def post(self):
        # 1. 接收数据，验证数据
        target = request.json.get('target')
        # 2.查询数据库，是否存在　点赞的信息
        cl = CommentLiking.query.filter_by(comment_id=target).first()

        if cl:
            # 如果存在，则修改状态
            cl.is_deleted = False
        else:
            # 如果不存，保存信息数据
            cl = CommentLiking(user_id=g.user_id, comment_id=target, is_deleted=False)
            db.session.add(cl)

        db.session.commit()
        # 添加缓存
        UserCommentLikingCache(g.user_id).user_liking_comment(g.user_id)
        # 清掉旧缓存
        UserCommentLikingCache(g.user_id).clear()
        # 返回相应
        return {'target': target}, 201


# 取消评论点赞
class CommentLikingDelete(Resource):
    method_decorators = [loginrequired]

    def delete(self, target):
        # 根据用户和文章找到对应的收藏文章  更新标记即可
        CommentLiking.query.filter_by(user_id=g.user_id, comment_id=target).update({'is_deleted': True})
        db.session.commit()
        # 清掉旧缓存
        UserCommentLikingCache(g.user_id).clear()
        return {'message': 'ok'}, 204
